<script setup lang="ts">
import {
  ArrowDown,
  ArrowUp,
} from '@element-plus/icons-vue'
/**
 * @see https://sangtian152.github.io/vue3-tree-org/demo/#attributes
 */
import { Vue3TreeOrg } from 'vue3-tree-org'
import { STORAGE_MODES } from '@/enum/modules/indicator'
import 'vue3-tree-org/lib/vue3-tree-org.css'
import IndicatorDataCurveModal from '@/components/IndicatorDataCurveModal/IndicatorDataCurveModal.vue'
import { getDefaultTimes } from '@/components/IndicatorDataCurveModal/composable'

import LinkFlow from './lineFlow'

const props = withDefaults(
  defineProps<{
    data: any
    contentExpand: boolean
    timeType: STORAGE_MODES
  }>(),
  {
    data() {
      return {}
    },
  },
)
const indicatorDataCurveModalRef = ref<InstanceType<typeof IndicatorDataCurveModal>>()
const allUlExpand = inject('allUlExpand', ref(false))
const vue3TreeOrgRef = ref<InstanceType<typeof Vue3TreeOrg>>()

const treeData = computed(() => {
  const d = unref(props.data)
  const recursive = (array: any[]): any[] => {
    return array.map((item: any) => {
      const children = item.children
      return {
        id: item.id,
        pid: item.parentId,
        label: (item.pointName || '').trim(),
        data: item.data,
        color: item.color,
        ulexpand: unref(allUlExpand),
        children:
          children && children.length > 0
            ? recursive(children)
            : undefined,
      }
    })
  }
  return {
    id: d.id,
    pid: d.parentId,
    label: d.pointName,
    data: d.data,
    color: d.color,
    ulexpand: unref(allUlExpand),
    children:
      d.children && d.children.length > 0
        ? recursive(d.children)
        : undefined,
  }
})

const timeText = computed(() => {
  const t = props.timeType
  if (t === STORAGE_MODES.MONTH) {
    return ['本月', '上月', '上上月']
  }
  if (t === STORAGE_MODES.YEAR) {
    return ['今年', '去年', '前年']
  }
  if (t === STORAGE_MODES.NOW) {
    return ['实时']
  }
  if (t === STORAGE_MODES.DAY) {
    return ['今日', '昨日', '前日']
  }
  if (t === STORAGE_MODES.HOUR) {
    return ['当前小时', '前一小时']
  }
  return []
})

const indicatorNumber = ref<string>()

async function clickIndicator(code: string) {
  indicatorNumber.value = code
  await nextTick()
  indicatorDataCurveModalRef.value?.showModal()
}

const linkFlow = shallowRef<LinkFlow>()

async function handleClickExpand(evt: Event, node: any) {
  evt.preventDefault()
  evt.stopPropagation()
  node.$$data.ulexpand = !node.$$data.ulexpand
  vue3TreeOrgRef.value?.restoreOrgchart()
  await nextTick()
  drawLinkFlow()
}

function drawLinkFlow() {
  if (linkFlow.value) {
    linkFlow.value.update()
  }
  else {
    linkFlow.value = new LinkFlow(unref(treeData))
  }
}

watch(
  () => unref(treeData),
  async () => {
    vue3TreeOrgRef.value?.restoreOrgchart()
    await nextTick()
    drawLinkFlow()
  },
  { deep: true },
)

watch(() => unref(allUlExpand), async () => {
  vue3TreeOrgRef.value?.restoreOrgchart()
  await nextTick()
  drawLinkFlow()
})

onBeforeUnmount(() => {
  linkFlow.value?.clean()
})
onMounted(async () => {
  vue3TreeOrgRef.value?.restoreOrgchart()
  await nextTick()
  drawLinkFlow()
})
</script>

<template>
  <div class="config-tree-org h-full w-full">
    <Vue3TreeOrg
      ref="vue3TreeOrgRef"
      class="xxx"
      :data="treeData" :tool-bar="{
        scale: true,
        restore: true,
        expand: false,
        zoom: true,
        fullscreen: true,
      }" :scalable="true" :define-menus="[]" :node-draggable="false" :draggable-on-node="true"
    >
      <template #default="{ node }">
        <div
          :id="`node-content-${node.$$data.id}`" class="node-content"
          :style="{
            background: node.$$data.color,
          }"
        >
          <div
            class="node-title relative" @click="
              (evt) => handleClickExpand(evt, node)
            "
          >
            {{ node.$$data.label }}
            <a
              v-if="
                node.$$data.data
                  && node.$$data.data.length > 1
              " style="
                cursor: pointer;
                color: #fff;
                font-size: 14px;
                position: absolute;
                right: 10px;
                top: 12px;
              "
            >
              <ElIcon>
                <component
                  :is="node.$$data.ulexpand ? ArrowUp : ArrowDown
                  "
                />
              </ElIcon>
            </a>
          </div>
          <ul
            v-if="node.$$data.data" class="border-top node-ul" :class="{
              'ul-expand': node.$$data.ulexpand,
            }"
          >
            <li
              v-for="item in node.$$data.data" :key="item.id" class="node-li group"
              @click="clickIndicator(item.indicatorNumber)"
            >
              <p class="transition-all group-hover:text-white">
                {{ item.indicatorName }}({{ item.unit }})
              </p>
              <p class="margin-0 flex items-center">
                <span class="margin-right-sm text-truncate">
                  {{ (item.dataList || [])[0]?.val ?? '--' }}
                </span>
                <strong class="fs-12 ml-auto">
                  {{ timeText[0] }}
                </strong>
              </p>
              <p
                :class="{
                  'opacity-0': timeType === STORAGE_MODES.NOW,
                }" class="margin-0 flex items-center"
              >
                <span class="margin-right-sm text-truncate">
                  {{ (item.dataList || [])[1]?.val ?? '--' }}
                </span>
                <strong class="fs-12 ml-auto">
                  {{ timeText[1] }}
                </strong>
              </p>
            </li>
          </ul>
        </div>
      </template>
    </Vue3TreeOrg>

    <!-- 指标数据折线图 -->
    <IndicatorDataCurveModal
      v-if="indicatorNumber" ref="indicatorDataCurveModalRef" :title="timeType !== STORAGE_MODES.NOW
        ? '指标数据折线图'
        : '实时数据折线图'
      " :indicator-number="indicatorNumber" :initial-time-type="props.timeType"
      v-bind="getDefaultTimes(props.timeType)"
    />
  </div>
</template>

<style lang="scss">
.config-tree-org {
  .tree-org-node__children:before,
  .tree-org-node:before,
  .tree-org-node:after {
    display: none;
  }
  .tree-org-node,
  .tree-org-node__content,
  .tree-org-node__children {
    position: static
  }
  .tree-org {
    position: relative;
  }
  .tree-org-node__children,
  .tree-org-node {
    padding-top: 40px;
    font-size: 0;
  }
  .tree-org-node.is-leaf,
  .tree-org-node.collapsed {
    padding-left: 30px;
    padding-right: 30px;
  }
  .tree-org-node__content {
    font-size: 14px;
  }
}
</style>

<style scoped lang="scss">
.node-content {
  min-width: 120px;
}

.node-title {
  padding: 10px 16px;
  color: #efefef;
  z-index: 11;
}

.node-ul,
.node-li {
  list-style: none;
}

.node-ul {
  padding-left: 0;
  margin: 0;
  max-height: 90px;
  overflow: hidden;
  transition: all 0.3s cubic-bezier(0.075, 0.82, 0.165, 1);

  &.ul-expand {
    max-height: none;
  }
}

.node-li {
  white-space: nowrap;
  padding: 0 16px;
  margin-top: 10px;
  margin-bottom: 10px;
  font-size: 14px;
  text-align: left;
  color: #efefef;
  cursor: pointer;
}
</style>
